package com.egg.facepay;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.tencent.wxpayface.IWxPayfaceCallback;
import com.tencent.wxpayface.WxPayFace;
import com.tencent.wxpayface.WxfacePayCommonCode;
import com.tencent.wxpayface.WxfacePayLoadingDialog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private final String TAG = "facepay";

    private AlertDialog dialog;

    private class AuthInfo {
        public String authinfo;
        public long expire_time = 0;
    }

    private AuthInfo authinfo;

    private EditText mPhone;
    private Button init,raw,pay,report,release;

    private static final String PARAMS_FACE_AUTHTYPE = "face_authtype";
    private static final String PARAMS_APPID = "appid";
    private static final String PARAMS_MCH_ID = "mch_id";
    private static final String PARAMS_STORE_ID = "store_id";
    private static final String PARAMS_AUTHINFO = "authinfo";
    private static final String PARAMS_OUT_TRADE_NO = "out_trade_no";
    private static final String PARAMS_TOTAL_FEE = "total_fee";
    private static final String PARAMS_TELEPHONE = "telephone";

    private static final String PARAMS_REPORT_TYPE = "type";
    private static final String PARAMS_REPORT_COST = "cost";

    private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private final int permissionRequestCode = 0x1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
//        WxfacePayLoadingDialog dialog = new WxfacePayLoadingDialog(this);
//        dialog.show();
        authinfo = new AuthInfo();
    }
    private void initView(){
        init = findViewById(R.id.btn_init);
        raw = findViewById(R.id.btn_raw);
        pay = findViewById(R.id.btn_pay);
        report = findViewById(R.id.btn_report);
        release = findViewById(R.id.btn_release);
        mPhone = findViewById(R.id.et_number);

        init.setOnClickListener(this);
        raw.setOnClickListener(this);
        pay.setOnClickListener(this);
        report.setOnClickListener(this);
        release.setOnClickListener(this);

    }

    private void requestPermission() {
        /**
         * 版本判断，大于23的时候才需要动态申请权限
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /**
             * 判断该权限是否已经获取
             */
            int i = ContextCompat.checkSelfPermission(this, permissions[0]);
            /**
             * PERMISSION_GRANTED  已经获取  PERMISSION_DENIED 拒绝
             */
            if (i != PackageManager.PERMISSION_GRANTED) {
                /**
                 * 如果为获取权限，弹框提示用户当前应用需要该权限的意图
                 */
                showDialogTipUserRequestPermission();
            } else {
//                transfer();
            }
        }
    }

        @Override
        public void onClick (View view){
            switch (view.getId()) {
                case R.id.btn_init:
                    Log.d(TAG, "onClick | init ");
                /* 代理功能示例

                //HashMap map = new HashMap();
                //map.put("port","8888");
                //map.put("ip","10.43.80.163");
                //服务调用
                //WxPayFace.getInstance().initWxpayface(this, map,new IWxPayfaceCallback(){
                */

                    WxPayFace.getInstance().initWxpayface(this, new IWxPayfaceCallback() {
                        @Override
                        public void response(Map info) throws RemoteException {
                            Log.d(TAG, "response | initWxpayface " + info.get("return_msg"));
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, "初始化完成", Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    });
                    break;
                case R.id.btn_raw:
                    Log.d(TAG, "onClick | get raw data ");
                    Toast.makeText(MainActivity.this, "serial.no: " + Build.SERIAL, Toast.LENGTH_LONG).show();
                    WxPayFace.getInstance().getWxpayfaceRawdata(new IWxPayfaceCallback() {
                        @Override
                        public void response(Map info) throws RemoteException {
                            Log.d(TAG, "response | getWxpayfaceRawdata " + info.get("rawdata"));
                            String rawdata = info.get("rawdata").toString();
                            try {
                                writeFileToSDCard(info.get("rawdata").toString());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, "获取rawdata成功，开始请求authinfo", Toast.LENGTH_SHORT).show();
                                }
                            });

                            try {
                                getAuthInfo(rawdata);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, "authinfo请求已发", Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    });
                    break;
                case R.id.btn_pay:
                    Log.d(TAG, "onClick | pay ");
                    HashMap params = new HashMap();
                    params.put(PARAMS_FACE_AUTHTYPE, "FACEPAY");
                    params.put(PARAMS_APPID, "10086");
                    params.put(PARAMS_MCH_ID, "12306");
                    params.put(PARAMS_STORE_ID, "12345");
                    params.put(PARAMS_OUT_TRADE_NO, "" + (System.currentTimeMillis() / 100000));
                    params.put(PARAMS_TOTAL_FEE, "22222");
                    String phone = mPhone.getText().toString();
                    params.put(PARAMS_TELEPHONE, phone);

                    //未获取rawdata的话不继续
                    if (authinfo.authinfo == null) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "请先获取rawdata", Toast.LENGTH_SHORT).show();
                            }
                        });
                        break;
                    }
                    params.put(PARAMS_AUTHINFO, authinfo.authinfo);

                    WxPayFace.getInstance().getWxpayfaceCode(params, new IWxPayfaceCallback() {
                        @Override
                        public void response(Map info) throws RemoteException {
                            final String code = info.get("return_code").toString();
                            Log.d(TAG, "response | getWxpayfaceCode " + info);

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
//                                mPayLayout.setVisibility(View.GONE);
//                                mResultTxt.setVisibility(View.VISIBLE);

                                    if (TextUtils.equals(code, WxfacePayCommonCode.VAL_RSP_PARAMS_SUCCESS)) {

                                        Toast.makeText(MainActivity.this, "支付完成", Toast.LENGTH_SHORT).show();

                                        try {
                                            Thread.sleep(2000);
                                        } catch (Exception e) {

                                        }

                                        WxPayFace.getInstance().updateWxpayfacePayResult(new HashMap(), new IWxPayfaceCallback() {
                                            @Override
                                            public void response(Map info) throws RemoteException {

                                            }
                                        });


                                    } else if (TextUtils.equals(code, WxfacePayCommonCode.VAL_RSP_PARAMS_USER_CANCEL)) {
//                                    mResultTxt.setText("用户取消");
                                        Toast.makeText(MainActivity.this, "用户取消", Toast.LENGTH_SHORT).show();

                                    } else if (TextUtils.equals(code, WxfacePayCommonCode.VAL_RSP_PARAMS_SCAN_PAYMENT)) {
//                                    mResultTxt.setText("扫码支付");
                                        Toast.makeText(MainActivity.this, "扫码支付", Toast.LENGTH_SHORT).show();

                                    }


//                                mResultTxt.setOnClickListener(new View.OnClickListener() {
//                                    @Override
//                                    public void onClick(View view) {
//                                        mPayLayout.setVisibility(View.VISIBLE);
//                                        mResultTxt.setVisibility(View.GONE);
//                                    }
//                                });


                                }
                            });

                        }
                    });
                    break;
                case R.id.btn_report:
                    Log.d(TAG, "onClick | report ");
                    Map info = new HashMap();
                    info.put(PARAMS_REPORT_TYPE, "PAY");
                    info.put(PARAMS_REPORT_COST, 100);
//                WxPayFace.getInstance().report(info);
                    break;
                case R.id.btn_release:
                    Log.d(TAG, "onClick | release ");
                    WxPayFace.getInstance().releaseWxpayface(this);
                    break;
            }
        }

        private void getAuthInfo (String rawdata) throws IOException {
            //AuthInfo info =  new AuthInfo();
            Log.d(TAG, "enter | getAuthInfo ");

            try {
                // Create a trust manager that does not validate certificate chains
                final TrustManager[] trustAllCerts = new TrustManager[]{
                        new X509TrustManager() {
                            @Override
                            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                            }

                            @Override
                            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                            }

                            @Override
                            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                return new java.security.cert.X509Certificate[]{};
                            }
                        }
                };

                // Install the all-trusting trust manager
                final SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
                // Create an ssl socket factory with our all-trusting manager
                final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

                OkHttpClient client = new OkHttpClient.Builder()
                        .sslSocketFactory(sslSocketFactory)
                        .hostnameVerifier(new HostnameVerifier() {
                            @Override
                            public boolean verify(String hostname, SSLSession session) {
                                return true;
                            }
                        })
                        .build();

                RequestBody body = RequestBody.create(null, rawdata);

                Request request = new Request.Builder()
                        .url("https://wxpay.wxutil.com/wxfacepay/api/getWxpayFaceAuthInfo.php")
                        .post(body)
                        .build();

                client.newCall(request)
                        .enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                Log.d(TAG, "onFailure | getAuthInfo " + e.toString());
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                //String responseXMLString=response.body().string();
                                try {
                                    authinfo.authinfo = ReturnXMLParser.parseGetAuthInfoXML(response.body().byteStream());
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                Log.d(TAG, "onResponse | getAuthInfo " + authinfo.authinfo);
                            }
                        });
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }

        private void writeFileToSDCard (String data) throws IOException {
            // 比如可以将一个文件作为普通的文档存储，那么先获取系统默认的文档存放根目录
            File parent_path = Environment.getExternalStorageDirectory();

            // 可以建立一个子目录专门存放自己专属文件
            final File file = new File(parent_path, "rawdata.txt");

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "文件路径:" + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
                }
            });

            // 创建这个文件，如果不存在
            file.createNewFile();

            FileOutputStream fos = new FileOutputStream(file);

            byte[] buffer = data.getBytes();

            // 开始写入数据到这个文件。
            fos.write(buffer, 0, buffer.length);
            fos.flush();
            fos.close();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "写成文件成功", Toast.LENGTH_LONG).show();
                }
            });

        }


        @Override
        protected void onDestroy () {
            WxPayFace.getInstance().releaseWxpayface(this);
            super.onDestroy();
        }

        // 提示用户去应用设置界面手动开启权限

    private void showDialogTipUserGoToAppSettting() {
        dialog = new AlertDialog.Builder(this)
                .setTitle(R.string.permission_denied)
                .setMessage(R.string.goto_setting)
                .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 跳转到应用设置界面
                        goToAppSetting();
                    }
                })
                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).setCancelable(false).show();
    }

    // 提示用户该请求权限的弹出框
    private void showDialogTipUserRequestPermission() {

        new AlertDialog.Builder(this)
                .setTitle(R.string.permission_dialog_tip)
                .setMessage(R.string.permission_dialog_message)
                .setPositiveButton(R.string.granted, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startRequestPermission();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(R.string.denied, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                }).setCancelable(false).show();
    }

    private void startRequestPermission() {
        ActivityCompat.requestPermissions(this, permissions, permissionRequestCode);
    }



    // 跳转到当前应用的设置界面
    private void goToAppSetting() {
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, 123);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 123) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // 检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(this, permissions[0]);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    // 提示用户应该去应用设置界面手动开启权限
                    showDialogTipUserGoToAppSettting();
                } else {
                    if (dialog != null && dialog.isShowing()) {
                        dialog.dismiss();
                    }
                    Toast.makeText(this, getString(R.string.acquire_permission_success), Toast.LENGTH_SHORT).show();

                }
            }
        }
    }
}
